package cn.itcast.service.cargo.impl;


import cn.itcast.dao.cargo.*;
import cn.itcast.domain.cargo.*;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductResult;
import cn.itcast.vo.ExportResult;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service
public class ExportServiceImpl implements ExportService {


    @Autowired
    private ExportDao exportDao;

    @Autowired
    private ContractDao contractDao;

    @Autowired
    private ContractProductDao contractProductDao;

    @Autowired
    private ExportProductDao exportProductDao;

    @Autowired
    private ExtCproductDao extCproductDao;

    @Autowired
    private ExtEproductDao extEproductDao;
    /*
     报运单分页
     */
    @Override
    public PageInfo<Export> findByPage(ExportExample exportExample, int pageNum, int pageSize) {

        //设置页面大小
        PageHelper.startPage(pageNum,pageSize);

        //查询全部
        List<Export> exportList = exportDao.selectByExample(exportExample);

        //封装PageInfo对象
        PageInfo<Export> pageInfo = new PageInfo<>(exportList);

        return pageInfo;
    }

    //查询全部
    @Override
    public List<Export> findAll(ExportExample exportExample) {

        List<Export> exportList = exportDao.selectByExample(exportExample);

        return exportList;
    }

    //根据主键查询
    @Override
    public Export findById(String id) {

        Export export = exportDao.selectByPrimaryKey(id);
        return export;
    }


    //保存报运单
    @Override
    public void save(Export export) {
        export.setId(UUID.randomUUID().toString());

        //1.往报运单插入一条记录
        //补全报运单的数据
        export.setInputDate(new Date());
        //查找合同号
        //找到该报运单下面的所有购销合同
        String[] contractIds = export.getContractIds().split(",");
        ContractExample contractExample = new ContractExample();
        contractExample.createCriteria().andIdIn(Arrays.asList(contractIds)); //Arrays.asList(contractIds) 把数组转换为集合
        List<Contract> contractList = contractDao.selectByExample(contractExample);

        //定义一个变量存储 合同号
        String contratNos = "";

        //存储所有购销合同货物的种类
        int totalProNum = 0;

        //存储所有购销合同货物的种类
        int totalExtNum = 0;

        //循环遍历每一个购销合同
        for (Contract contract : contractList) {
            contratNos += contract.getContractNo();
            totalProNum += contract.getProNum();
            totalExtNum += contract.getExtNum();
            // 2.报运单下面的购销合同的状态从1改为2 ,  （购销合同的状态：
            // 0（草稿，草稿状态下的合同不能申请报运） 1(允许被报运了) ，  2（已经生成报运单合同））
            contract.setState(2);
            //更新当前购销合同
            contractDao.updateByPrimaryKeySelective(contract);
        }

        //把合同号设置到报运单上
        export.setCustomerContract(contratNos);
        //设置报运单的状态 ， 报运单状态有三种 0(草稿)  1(已提交，提交的报运单可以向海关报运)  2(已经向海关报运的报运单)
        export.setState(0);
        //设置货物的种类
        export.setProNum(totalProNum);
        //设置附件的种类
        export.setExtNum(totalExtNum);

        exportDao.insertSelective(export);

        //3.把购销合同下的所有货物数据导入到 报运商品表中
        //查询购销合同下的所有货物
        ContractProductExample contractProductExample = new ContractProductExample();
        contractProductExample.createCriteria().andContractIdIn(Arrays.asList(contractIds));
        List<ContractProduct> contractProductList = contractProductDao.selectByExample(contractProductExample);

        //定义一个Map集合存储  购销合同货物的id与报运货物的id
        Map<String , String> map = new HashMap<>();

        //遍历所有购销合同中的货物
        for (ContractProduct contractProduct : contractProductList) {
            //一个购销合同货物对于一个 报运单的商品数据
            ExportProduct exportProduct = new ExportProduct();
            //把contractProduct的属性数据拷贝到exportProduct对象，要求属性名一致即可
            BeanUtils.copyProperties(contractProduct,exportProduct);
            //报运单 商品id
            exportProduct.setId(UUID.randomUUID().toString());

            //报运商品 所属报运单id
            exportProduct.setExportId(export.getId());

            //map的key：购销合同货物的id  ， value： 报运商品的id
            map.put(contractProduct.getId(), exportProduct.getId());

            //把保运商品插入到数据库中
            exportProductDao.insertSelective(exportProduct);

        }

        //4.把报运单下的购销合同下的所有货物的附件数据导入到   报运商品附件表中
        //找到购销合同的所有附件
        ExtCproductExample extCproductExample = new ExtCproductExample();

        //条件：购销合同的id
        extCproductExample.createCriteria().andContractIdIn(Arrays.asList(contractIds));
        List<ExtCproduct> extCproductList = extCproductDao.selectByExample(extCproductExample);

        //遍历购销合同的所有附件
        if(extCproductList!=null) {
            for (ExtCproduct extCproduct : extCproductList) {
                //购销合同的一个附件就对应报运单表的一个附件
                ExtEproduct extEproduct = new ExtEproduct();
                //拷贝属性
                BeanUtils.copyProperties(extCproduct, extEproduct);
                //报运附件设置id
                extEproduct.setId(UUID.randomUUID().toString());
                //报运附件设置所属的报运单
                extEproduct.setExportId(export.getId());
                //报运附件设置所属报运商品
                extEproduct.setExportProductId(map.get(extCproduct.getContractProductId()));
                //插入数据
                extEproductDao.insertSelective(extEproduct);
            }
        }

    }

    //更新报运单
    @Override
    public void update(Export export) {
        //1. 更新报运单
        exportDao.updateByPrimaryKeySelective(export);

        //2 更新报运商品
        List<ExportProduct> exportProducts = export.getExportProducts();
        if(exportProducts!=null) {
            for (ExportProduct exportProduct : exportProducts) {
                exportProductDao.updateByPrimaryKeySelective(exportProduct);
            }
        }
    }

    //删除报运单
    @Override
    public void delete(String id) {
        exportDao.deleteByPrimaryKey(id);
    }


    //根据海关返回报运结果更新报运单的信息以及商品的税收
    @Override
    public void updateByResult(ExportResult exportResult) {
        Export export = exportDao.selectByPrimaryKey(exportResult.getExportId());
        //把报运结果的状态赋予给报运单
        export.setState(exportResult.getState());

        //备注信息
        export.setRemark(exportResult.getRemark());
        exportDao.updateByPrimaryKeySelective(export);

        //获取到报运商品
        Set<ExportProductResult> products = exportResult.getProducts();

        if (products!=null){
            for (ExportProductResult product : products) {
                //查找到对应的商品
                ExportProduct exportProduct = exportProductDao.selectByPrimaryKey(product.getExportProductId());

                //给商品设置税收
                exportProduct.setTax(product.getTax());

                //把商品信息更新回数据库
                exportProductDao.updateByPrimaryKeySelective(exportProduct);
            }
        }

    }

    @Override
    public String checkPacking(String[] id) {
        //找到需要装箱的运单
        ExportExample exportExample = new ExportExample();
        exportExample.createCriteria().andIdIn(Arrays.asList(id));
        List<Export> exportList = exportDao.selectByExample(exportExample);

        //定义集合存放装运港信息
        List<String> shipmentPorts = new ArrayList<String>();
        //定义集合存放目的港信息
        List<String> destinationPorts = new ArrayList<String>();
        //定义集合存放收货人信息
        List<String> consignees = new ArrayList<String>();

        //定义集合存放状态信息
        List<Integer> stateList = new ArrayList<Integer>();

        //把运单中装运港信息抽取到集合中
        for (Export export : exportList) {
            String sp = export.getShipmentPort();
            String dp = export.getDestinationPort();
            String c = export.getConsignee();

            Integer state = export.getState();

            shipmentPorts.add(sp);
            destinationPorts.add(dp);
            consignees.add(c);
            stateList.add(state);
        }


        //判断 状态是否都为 以报运
        if (stateList != null) {
            //草稿状态为 0
            Integer s = 0;
            //让集合中的其他信息与 0 进行比较
            for (Integer state : stateList) {
                if (s.equals(state)) {
//                    return "[报运状态]有误!!";
                    return "1";
                }
            }

            //已装箱状态为 3
            Integer s2 = 3;
            //让集合中的其他信息与 0 进行比较
            for (Integer state : stateList) {
                if (s2.equals(state)) {
//                    return "[已装箱]有误!!";
                    return "6";
                }
            }


            //循环完毕 装运港信息 匹配成功
        }


        //判断 装运港信息 是否匹配
        if (shipmentPorts != null) {
            //获取第一个信息
            String sp = shipmentPorts.get(0);
            //让集合中的其他信息与第一个进行比较
            for (String shipmentPort : shipmentPorts) {
                if (!sp.equals(shipmentPort)) {
//                    return "[装运港]信息，不匹配!!";
                    return "2";
                }
            }
            //循环完毕 装运港信息 匹配成功
        }


        //判断 目的港信息 是否匹配
        if (destinationPorts != null) {
            //获取第一个信息
            String dp = destinationPorts.get(0);
            //让集合中的其他信息与第一个进行比较
            for (String destinationPort : destinationPorts) {
                if (!dp.equals(destinationPort)) {
//                    return "[目的港]信息，不匹配!!";
                    return "3";
                }
            }
            //循环完毕 装运港信息 匹配成功
        }

        //判断 收货人信息 是否匹配
        if (consignees != null) {
            //获取第一个信息
            String c = consignees.get(0);
            //让集合中的其他信息与第一个进行比较
            for (String consignee : consignees) {
                if (!c.equals(consignee)) {
//                    return "[收货人]信息，不匹配!!";
                    return "4";
                }
            }
            //循环完毕 装运港信息 匹配成功
        }

        //符合装箱条件

        //把id集合转 字符串
//        String ids = ArrayUtils.toString(id, ","); // 数组转字符串(逗号分隔,首尾加大括号) {0,1,2,3,4,5}
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < id.length; i++) {
            if (i == id.length-1){
                stringBuilder.append(id[i]);
            }else {
                stringBuilder.append(id[i]).append(",");
            }
        }
        String ids = stringBuilder.toString();
        //成功  返回所有id拼接的字符串
        return ids;
    }

    @Override
    public Export findByNo(String s) {
        return exportDao.findByNo(s);
    }


}
